<template>
  <view class="wrap">
    <button type="primary" @tap="chooseSource">上传图片</button>

    <!-- 预览 -->
    <image v-if="preview" :src="preview" mode="widthFix" class="preview" />

    <!-- 上传进度 -->
    <progress v-if="uploading" :percent="percent" stroke-width="8" />
  </view>
</template>

<script>
export default {
  data() {
    return {
      preview: '',   // 本地预览图
      uploading: false,
      percent: 0
    };
  },
  methods: {
    /* 1. 弹出拍照/相册选择 + 权限处理 */
    chooseSource() {
      // 先检查相册/相机权限
      this.checkAuth().then(() => {
        uni.showActionSheet({
          itemList: ['拍照', '从相册选择'],
          success: (res) => {
            const sourceType = res.tapIndex === 0 ? ['camera'] : ['album'];
            this.chooseImage(sourceType);
          }
        });
      });
    },

    /* 2. 统一权限申请（相机+相册） */
    checkAuth() {
      return new Promise((resolve, reject) => {
        uni.getSetting({
          success: (res) => {
            const cameraOk = res.authSetting['scope.camera'];
            const albumOk  = res.authSetting['scope.writePhotosAlbum'];
            // 只要有一个没授权，就都重新授权一遍，避免第二次弹不出来
            const needAuth = [];
            if (cameraOk !== true) needAuth.push('scope.camera');
            if (albumOk  !== true) needAuth.push('scope.writePhotosAlbum');

            if (needAuth.length === 0) return resolve();

            let finishCount = 0;
            needAuth.forEach(scope => {
              uni.authorize({
                scope,
                complete: () => {
                  finishCount++;
                  if (finishCount === needAuth.length) resolve();
                }
              });
            });
          }
        });
      });
    },

    /* 3. 选图 + 压缩 + 上传 */
    chooseImage(sourceType) {
      uni.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        sourceType,
        success: (res) => {
          this.preview = res.tempFilePaths[0];
          this.compressAndUpload(res.tempFilePaths[0]);
        }
      });
    },

    compressAndUpload(src) {
      uni.compressImage({
        src,
        quality: 80,
        success: (res) => this.uploadImage(res.tempFilePath)
      });
    },

    uploadImage(filePath) {
      this.uploading = true;
      this.percent = 0;

      uni.uploadFile({
        url: 'https://your-server.com/api/upload',
        filePath,
        name: 'file',
        formData: { from: 'uniapp' },
        success: (res) => {
          const data = JSON.parse(res.data);
          uni.showToast({ title: data.url ? '上传成功' : '上传失败' });
        },
        fail: () => uni.showToast({ title: '网络错误', icon: 'none' }),
        complete: () => (this.uploading = false),
        onProgressUpdate: e => (this.percent = e.progress)
      });
    }
  }
};
</script>

<style scoped>
.wrap{padding:40rpx}
button{margin-bottom:30rpx}
.preview{width:90%;border-radius:12rpx;margin:20rpx auto;display:block}
</style>